Skip to content

Allow preprocessor in example modules - #11486

Open
garazdawi wants to merge 10 commits into
erlang:masterfrom
garazdawi:lukas/ct/allow-preprocessor-in-example-modules
Open

Allow preprocessor in example modules#11486
garazdawi wants to merge 10 commits into
erlang:masterfrom
garazdawi:lukas/ct/allow-preprocessor-in-example-modules

Conversation

@garazdawi

Copy link
Copy Markdown
Member

This PR adds support for the preprocessor when parsing example module code using ct_doctest. It does this by adding some other new features:

  1. Allows ram files to be cooked, that is they return a pid() instead of a raw handle. This makes it possible to use functions in the io module that epp needs.
  2. Add an option to pass an open file to epp:parse_file so that we can pass the cooked ram file.
  3. Add an option to pass a callback fun for reading includes so that include files can be provided without touching disk.
  4. Add compile:string/1,2 that instructs the compiler to compile an Erlang module from the provided string.

Then I've put all this together so that ct_doctest uses compile:string() to compile module examples so that tuple records, macros and other epp features work.

I think the compiler:string/1,2 function could be useful for a variety of things as it makes it much easier to turn generated code strings into runnable code.

While doing this I also added doctests for epp and compile.

I've added special "since" commits that should be updated with the correct ticket number if/when we merge this.

This commit makes ram files work as I/O servers so that code that
expects I/O server can use ram files, for example epp:open.
This enables fully in-memory preprocessing using cooked ram files.
Add compile:string/1,2 and compile:noenv_string/2 that compile Erlang
source code from a string or binary. Unlike compile:forms, the source
goes through the Erlang preprocessor (epp), supporting -define, -include,
-ifdef, records, and all other preprocessor directives.

The `{include_path_open, Fun}` option is passed through to epp, enabling
fully in-memory compilation without file system access for include files.
@garazdawi
garazdawi requested a review from bjorng August 14, 2026 12:20
@github-actions

github-actions Bot commented Aug 14, 2026

Copy link
Copy Markdown
Contributor

CT Test Results

     5 files     530 suites   3h 34m 15s ⏱️
 5 088 tests  4 612 ✅ 475 💤 1 ❌
10 611 runs  10 066 ✅ 544 💤 1 ❌

For more details on these failures, see this check.

Results for commit 80537f6.

♻️ This comment has been updated with latest results.

To speed up review, make sure that you have read Contributing to Erlang/OTP and that all checks pass.

See the TESTING and DEVELOPMENT HowTo guides for details about how to run test locally.

Artifacts

// Erlang/OTP Github Action Bot

@jhogberg jhogberg added the team:VM Assigned to OTP team VM label Aug 17, 2026
@bjorng bjorng added the testing currently being tested, tag is used by OTP internal CI label Aug 17, 2026
@u3s

u3s commented Aug 24, 2026

Copy link
Copy Markdown
Contributor

@bjorng can you provide related OTP ticket number?

Symptom: Lab test otp_SUITE:test_runtime_dependencies_versions fails on master-opu (progress_30) with:

Undefined functions in common_test-1.31.1:
compile:string/2

Root cause: ct_doctest.erl now calls compile:string/2 which only exists in the compiler version introduced by this same branch. The declared minimum runtime dependency (compiler-10.0) doesn't have this function, so xref correctly flags it as undefined against older compiler versions.

Fix: Bump the compiler version in lib/common_test/src/common_test.app.src runtime_dependencies to the compiler version that includes compile:string/2 (i.e. the version this branch produces).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

team:VM Assigned to OTP team VM testing currently being tested, tag is used by OTP internal CI

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants